// Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.IO;
using Microsoft.WindowsAPICodePack.DirectX.Direct3D10;
using Microsoft.WindowsAPICodePack.DirectX.DirectXUtilities;

namespace WindowsFlag
{
    /// <summary>
    /// This class wraps the shaders
    /// </summary>
    internal class Effects
    {
        #region Private fields
        Effect effect;
        EffectTechnique technique;
        EffectMatrixVariable worldVariable;
        EffectMatrixVariable viewVariable;
        EffectMatrixVariable projectionVariable;

        EffectVectorVariable lightDirVariable;
        EffectVectorVariable lightColorVariable;
        EffectVectorVariable baseColorVariable;

        float[,] vLightDirs =
        {
            { 0.0f, 1.0f, 3.0f, 1.0f },
            { 0.0f, 1.0f, -3.0f, 1.0f },
        };

        float[,] vLightColors = 
        {
            { 0.25f, 0.25f, 0.25f, 0.25f },
            { 0.25f, 0.25f, 0.25f, 0.25f }
        };
        
        #endregion

        #region Internal properties
        internal Matrix4F WorldMatrix
        {
            set
            {
                worldVariable.SetMatrix(value.ToArray());
            }
        }

        internal Matrix4F ViewMatrix
        {
            set
            {
                viewVariable.SetMatrix(value.ToArray());
            }
        }

        internal Matrix4F ProjectionMatrix
        {
            set
            {
                projectionVariable.SetMatrix(value.ToArray());
            }
        }

        internal float[] BaseColor
        {
            set
            {
                baseColorVariable.SetFloatVector(value);
            }
        }

        internal EffectTechnique Technique
        {
            get
            {
                return technique;
            }
        } 
        #endregion

        public Effects(D3DDevice device)
        {
            using (FileStream effectStream = File.OpenRead("WindowsFlag.fxo"))
            {
                effect = device.CreateEffectFromCompiledBinary(new BinaryReader(effectStream));
            }
            // Obtain the technique
            technique = effect.GetTechniqueByName("Render");

            // Obtain the variables
            worldVariable = effect.GetVariableByName("World").AsMatrix();
            viewVariable = effect.GetVariableByName("View").AsMatrix();
            projectionVariable = effect.GetVariableByName("Projection").AsMatrix();

            lightDirVariable = effect.GetVariableByName("vLightDir").AsVector();
            lightColorVariable = effect.GetVariableByName("vLightColor").AsVector();
            baseColorVariable = effect.GetVariableByName("vBaseColor").AsVector();

            // Set constants
            lightColorVariable.SetFloatVectorArray(vLightColors);
            lightDirVariable.SetFloatVectorArray(vLightDirs);
        }
    }
}
